<template>
  <div class="OrganizationalStructure">
    <el-breadcrumb separator="/">
      <el-breadcrumb-item>系统管理</el-breadcrumb-item>
      <el-breadcrumb-item v-if="!ifShowDeactivate"
        ><a>组织架构</a></el-breadcrumb-item
      >
      <el-breadcrumb-item v-else>组织架构</el-breadcrumb-item>
      <el-breadcrumb-item v-if="ifShowDeactivate"
        ><a>停用列表</a></el-breadcrumb-item
      >
    </el-breadcrumb>
    <div class="OrganizationalStructure-content">
      <div class="select-range-content">
        <div class="left-content" v-if="ifShowStructure">
          <el-input
            prefix-icon="el-icon-search"
            placeholder="请输入内容"
            v-model="searchContent"
            @input="searchFn"
          ></el-input>
          <el-tree
            :indent="indent"
            :props="treeProps"
            :load="loadNode"
            :show-checkbox="false"
            lazy
            node-key="dept_id"
            class="scroll-content"
            highlight-current
            :default-checked-keys="['1']"
            :default-expanded-keys="['1']"
            @node-click="nodeClick"
            ref="tree"
            v-show="!searchContent"
          >
            <span class="custom-tree-node" slot-scope="{ node, data }">
              <span>{{ data.dept_name }}</span>
              <el-popover
                placement="bottom-end"
                trigge="click"
                popper-class="os-popper"
              >
                <div>
                  <div class="section-item" @click="adddepartment(data)">
                    添加子部门
                  </div>
                  <div
                    class="section-item"
                    @click="editname(data)"
                    v-if="data.parent"
                  >
                    修改名称
                  </div>
                  <div class="section-item" @click="setleader(data)">
                    设置部门负责人
                  </div>
                  <div
                    class="section-item"
                    @click="dletedepartment(data)"
                    v-if="node.data.dept_id != 1"
                  >
                    删除
                  </div>
                  <div
                    class="section-item"
                    @click="deptMoveOrder(data, -1)"
                    v-if="node.previousSibling"
                  >
                    上移
                  </div>
                  <div
                    class="section-item"
                    @click="deptMoveOrder(data, 1)"
                    v-if="node.nextSibling"
                  >
                    下移
                  </div>
                  <div class="section-id">部门ID：{{ data.dept_id }}</div>
                </div>
                <i
                  slot="reference"
                  class="el-icon-more"
                  style="margin-right: 10px"
                  v-if="ifCanEdit"
                ></i>
              </el-popover>
            </span>
          </el-tree>
          <el-tree
            :props="{
              label: 'dept_name',
              isLeaf: true,
            }"
            node-key="dept_id"
            :data="searchDepts"
            class="scroll-content"
            v-show="searchContent"
            @node-click="nodeClick"
            highlight-current
          >
          </el-tree>
        </div>
        <div class="right-content scroll-content">
          <div class="content-index" v-if="!ifShowDetails">
            <div class="right-title">
              <div class="title-left">
                <h1>
                  {{ currentNode.name }}({{ deptDetails.length }}人) (部门ID：{{
                    currentNode.dept_id
                  }})
                </h1>
                <el-tooltip content="复制部门ID" placement="bottom">
                  <i
                    class="el-icon-copy-document"
                    @click="copy(currentNode.dept_id)"
                  ></i>
                </el-tooltip>
              </div>
              <a v-if="!ifShowDeactivate" href="#" @click="toDeactivate"
                >停用列表</a
              >
            </div>
            <div class="buttons">
              <el-button
                type="primary"
                :icon="
                  ifShowDeactivate ? undefined : 'el-icon-circle-plus-outline'
                "
                size="small"
                @click="primaryClick"
                v-if="
                  (!ifShowDeactivate && ifCanAddEmployee) ||
                  (ifShowDeactivate && ifCanChangeEmployeeStatus)
                "
                >{{ ifShowDeactivate ? "恢复" : "邀请成员" }}</el-button
              >
              <el-button
                size="small"
                @click="normalClick"
                v-if="
                  (!ifShowDeactivate && ifCanChangeEmployeeStatus) ||
                  ifShowDeactivate
                "
                >{{ ifShowDeactivate ? "返回" : "停用" }}</el-button
              >
            </div>
            <el-table
              :data="deptDetails"
              @row-click="rowClick"
              @select="select"
              ref="elTable"
            >
              <el-table-column type="selection" width="48"></el-table-column>
              <el-table-column label="姓名" prop="dept_name" width="100">
                <template slot-scope="scope">
                  <show-person :personInfo="scope.row" />
                </template>
              </el-table-column>
              <el-table-column label="部门" prop="dept" show-overflow-tooltip>
                <template slot-scope="scope">
                  {{
                    scope.row.all_department.reduce((res, cur, ind, array) => {
                      return (res +=
                        scope.row.main_dept_id === cur.dept_id
                          ? cur.dept_name +
                            (main_dept_hide ? "" : "(主)") +
                            (ind === array.length - 1 ? "" : "、")
                          : cur.dept_name +
                            (main_dept_hide ? "(兼)" : "") +
                            (ind === array.length - 1 ? "" : "、"));
                    }, "")
                  }}
                </template>
              </el-table-column>
              <el-table-column
                label="账号"
                prop="employee_id"
              ></el-table-column>
              <el-table-column label="手机号" prop="phone_number">
                <template slot-scope="scope">
                  {{ scope.row.phone_number ?? "/" }}
                </template>
              </el-table-column>
              <el-table-column label="邮箱" prop="email">
                <template slot-scope="scope">
                  {{ scope.row.email ?? "/" }}
                </template>
              </el-table-column>
              <el-table-column label="操作" width="60" v-if="ifCanEdit">
                <template slot-scope="scope">
                  <el-popover
                    placement="top"
                    width="100"
                    trigger="hover"
                    popper-class="os-operate-popper"
                  >
                    <div
                      class="popover-options"
                      v-for="item in popoverOptions"
                      @click="popoverClick(item.value, scope.row)"
                      :key="item.value"
                    >
                      <div
                        class="section-item"
                        v-if="
                          item.value !== 'deactivate' ||
                          ifCanChangeEmployeeStatus
                        "
                      >
                        {{ item.label }}
                      </div>
                    </div>
                    <i
                      class="el-icon-more"
                      slot="reference"
                      v-if="!ifShowDeactivate"
                    ></i>
                  </el-popover>
                  <el-button
                    type="text"
                    v-if="ifShowDeactivate && ifCanChangeEmployeeStatus"
                    @click.stop.native="restore(scope.row)"
                    >恢复</el-button
                  >
                </template>
              </el-table-column>
            </el-table>
            <el-pagination
              @size-change="handleSizeChange"
              @current-change="handleCurrentChange"
              :current-page="paginationInfo.currentPage"
              :page-sizes="[10, 20, 50, 100]"
              :page-size="paginationInfo.pageSize"
              layout="total, sizes, prev, pager, next, jumper"
              :total="paginationInfo.total"
              background
            >
            </el-pagination>
          </div>
          <div class="content-details" v-else>
            <person-details
              :personInfo="clickRow"
              :type="personDetailsType"
              ref="personDetails"
              @back="() => (ifShowDetails = false)"
              @cancel="() => (ifShowDetails = false)"
              @deactivate="deactivate"
              @changePassword="changePassword"
              @edit="editPerson"
              @refrushPersons="refrushPersons"
              @restore="restore"
            />
          </div>
        </div>
      </div>
    </div>
    <el-dialog
      :title="leftMode === 'addSubDept' ? '添加子部门' : '修改名称'"
      :visible.sync="leftDialogVisible"
      width="30%"
    >
      <el-form :model="leftDialogForm" ref="leftDialogForm">
        <el-form-item
          :rules="[
            { required: true, message: '部门名称不可为空', tigger: 'change' },
          ]"
          prop="deptName"
        >
          <el-input
            v-model="leftDialogForm.deptName"
            placeholder="请输入部门名称"
            maxlength="32"
            show-word-limit
          ></el-input>
        </el-form-item>
      </el-form>
      <span slot="footer" class="dialog-footer">
        <el-button @click="leftDialogVisible = false">取 消</el-button>
        <el-button type="primary" @click="leftDialogSubmit">确 定</el-button>
      </span>
    </el-dialog>
    <tree-search
      @changeDialogVisible="changeDialogVisible"
      @dialogSubmit="dialogSubmit"
      :dialogVisible="dialogVisible"
      title="设置部门负责人"
      :dept="currentNode"
      :selected_employee="currentNode.dept_header"
      mode="employee"
    />
    <el-dialog title="修改密码" :visible.sync="rightDialogVisible" width="30%">
      <el-form :model="rightDialogForm" :rules="rules" ref="rightForm">
        <el-form-item label="新密码" prop="newPassword" required>
          <el-input
            v-model="rightDialogForm.newPassword"
            placeholder="8-20位, 必须包含英文大小写和数字"
            maxlength="20"
            type="password"
          ></el-input>
        </el-form-item>
        <el-form-item label="确认新密码" prop="confirmNewPassword" required>
          <el-input
            v-model="rightDialogForm.confirmNewPassword"
            placeholder="再次输入新密码"
            maxlength="20"
            type="password"
          ></el-input>
        </el-form-item>
      </el-form>
      <span slot="footer" class="dialog-footer">
        <el-button @click="rightDialogVisible = false">取 消</el-button>
        <el-button type="primary" @click="rightDialogSubmit">确 定</el-button>
      </span>
    </el-dialog>
  </div>
</template>

<script>
import tool from "@/utils/tools";
import showPerson from "@/components/public/showPerson.vue";
import PersonDetails from "@/components/systemtools/PersonDetails";
import treeSearch from "@/components/public/treeSearch.vue";
import {
  deactivateEmployee,
  getPersonInDept,
  getRootNode,
  getTargetNodes,
  restoreEmployee,
  changePassword,
  addSubDept,
  changeDeptName,
  deleteDept,
  deptMove,
  setDeptHeader,
  searchDept,
  getAllSettingsMap,
} from "@/http/api";
export default {
  name: "OrganizationalStructure",
  components: { showPerson, PersonDetails, treeSearch },
  data() {
    return {
      searchContent: "",
      treeProps: {
        label: "dept_name",
        isLeaf: "leaf",
      },
      currentNode: {},
      deptDetails: [],
      indent: 8,
      ifShowDeactivate: false,
      ifShowDetails: false,
      popoverOptions: [
        {
          label: "编辑",
          value: "edit",
        },
        {
          label: "停用",
          value: "deactivate",
        },
        {
          label: "修改密码",
          value: "changePassword",
        },
      ],
      clickRow: {},
      selectedRows: [],
      leftDialogVisible: false,
      leftDialogForm: {
        deptName: "",
      },
      leftDialogCurrentDept: {},
      dialogVisible: false,
      leftMode: "",
      rightDialogVisible: false,
      rightDialogForm: {
        newPassword: "",
        confirmNewPassword: "",
      },
      rules: {
        newPassword: [
          {
            required: true,
            validator: (_, value, callback) => {
              if (value) {
                let ISPWD =
                  /^(?=.*[0-9])(?=.*[A-Z])(?=.*[a-z])[0-9a-zA-Z]{8,20}/;
                if (ISPWD.test(value)) {
                  callback();
                } else {
                  callback(
                    new Error("密码要求8-20位, 必须包含英文大小写和数字")
                  );
                }
              } else {
                callback(new Error("请输入新密码"));
              }
            },
          },
        ],
        confirmNewPassword: [
          {
            required: true,
            validator: (_, value, callback) => {
              if (value === this.rightDialogForm.newPassword) {
                if (value) {
                  callback();
                } else {
                  callback(new Error("两次输入的密码需一致"));
                }
              } else {
                callback(new Error("请输入确认密码"));
              }
            },
          },
        ],
      },
      changePasswordPerson: {},
      personDetailsType: "",
      paginationInfo: {
        current_page: 1,
        total: 0,
        page_size: 10,
      },
      searchDepts: [],
      main_dept_hide: 0,
      ifCanAddEmployee: false,
      ifCanEdit: false,
      ifShowStructure: false,
      ifSeemployeeDetails: false,
      ifCanChangeEmployeeStatus: false,
    };
  },
  async mounted() {
    let authDetail = JSON.parse(localStorage.getItem("authority"));
    if (authDetail === "all") {
      this.ifCanAddEmployee = true;
      this.ifCanEdit = true;
      this.ifShowStructure = true;
      this.ifSeemployeeDetails = true;
      this.ifCanChangeEmployeeStatus = true;
    } else {
      this.ifCanAddEmployee = authDetail.includes("AddEmployee") ? true : false;
      this.ifCanEdit = authDetail.includes("EditEmployee") ? true : false;
      this.ifShowStructure = authDetail.includes("ShowStructure")
        ? true
        : false;
      this.ifSeemployeeDetails = authDetail.includes("SeemployeeDetails")
        ? true
        : false;
      this.ifCanChangeEmployeeStatus = authDetail.includes(
        "ChangeEmployeeStatus"
      )
        ? true
        : false;
    }
    let res = await getAllSettingsMap();
    if (res.code === 20041) {
      this.main_dept_hide = res.data.main_dept_hide;
    }
  },
  updated() {
    this.$nextTick(() => {
      this.$refs.elTable && this.$refs.elTable.doLayout();
    });
  },
  methods: {
    async loadNode(node, resolve) {
      if (node.level === 0) {
        let res = await getRootNode();
        let root = {};
        if (res.code === 20041) {
          root = res.data;
        }
        setTimeout(async () => {
          this.currentNode = root;
          this.$refs.tree.setCurrentNode(root);
          this.nodeClick(root);
        });
        return resolve([root]);
      }
      let res = await getTargetNodes(node.data.dept_id);
      if (res.code === 20041) {
        resolve(res.data);
      }
    },
    async nodeClick(object) {
      (this.paginationInfo = {
        current_page: 1,
        total: 0,
        page_size: 10,
      }),
        (this.currentNode = object);
      let res = await getPersonInDept({
        ...this.paginationInfo,
        worker_id: object.worker_id,
        status: this.ifShowDeactivate ? 0 : 1,
      });
      if (res.code === 20041) {
        this.paginationInfo = res.data.page;
        this.deptDetails = res.data.rows;
      }
    },
    adddepartment(node) {
      this.leftMode = "addSubDept";
      this.leftDialogForm.deptName = "";
      this.leftDialogCurrentDept = node;
      this.leftDialogVisible = true;
      this.$nextTick(() => {
        this.$refs.leftDialogForm.clearValidate();
      });
    },
    editname(node) {
      this.leftMode = "editName";
      this.leftDialogForm.deptName = node.dept_name;
      this.leftDialogCurrentDept = node;
      this.leftDialogVisible = true;
    },
    setleader(node) {
      this.leftDialogCurrentDept = node;
      this.dialogVisible = true;
    },
    dletedepartment(node) {
      if (node.leaf && !node.worker_id) {
        this.$alert(`是否确认删除【${node.dept_name}】部门`, "删除", {
          confirmButtonText: "确定",
          showCancelButton: true,
          callback: async (action) => {
            if (action === "confirm") {
              let res = await deleteDept(node.dept_id);
              if (res.code === 20021) {
                this.$message({
                  message: "删除成功",
                  type: "success",
                });
              } else {
                this.$message.error(res.msg);
              }
            }
          },
        });
      } else {
        this.$alert("请删除此部门下的成员或子部门后，再删除此部门", "删除", {
          confirmButtonText: "确定",
          showCancelButton: true,
        });
      }
    },
    async deptMoveOrder(node, direction) {
      let res = await deptMove({
        dept_id: node.dept_id,
        direction,
      });
      if (res.code === 20031) {
        this.$message.success("移动成功");
      } else {
        this.$message.error(res.msg);
      }
    },
    async copy(data) {
      await tool.copy(data);
      this.$message({
        message: "复制成功",
        type: "success",
      });
    },
    async toDeactivate() {
      (this.paginationInfo = {
        current_page: 1,
        total: 0,
        page_size: 10,
      }),
        (this.ifShowDeactivate = true);
      let res = await getPersonInDept({
        ...this.paginationInfo,
        worker_id: this.currentNode.worker_id,
        status: 0,
      });
      if (res.code === 20041) {
        this.paginationInfo = res.data.page;
        this.deptDetails = res.data.rows;
      }
    },
    async normalClick() {
      if (this.ifShowDeactivate) {
        this.ifShowDeactivate = false;
        let res = await getPersonInDept({
          ...this.paginationInfo,
          worker_id: this.currentNode.worker_id,
          status: 1,
        });
        if (res.code === 20041) {
          this.paginationInfo = res.data.page;
          this.deptDetails = res.data.rows;
        }
      } else {
        if (this.selectedRows.length) {
          this.deactivate();
        } else {
          this.$message({
            message: "请先选择要停用的成员",
            type: "warning",
          });
        }
      }
    },
    async primaryClick() {
      if (this.ifShowDeactivate) {
        // 恢复
        this.restore();
      } else {
        // 新增成员
        this.personDetailsType = "add";
        this.ifShowDetails = true;
        this.clickRow = {};
        setTimeout(() => {
          this.$refs.personDetails.changeToEdit(this.currentNode);
        });
      }
    },
    popoverClick(type, row) {
      if (type === "deactivate") {
        this.deactivate(row);
      }
      if (type === "changePassword") {
        this.changePassword(row);
      }
      if (type === "edit") {
        this.editPerson(row);
      }
    },
    rowClick(row) {
      this.personDetailsType = this.ifShowDeactivate
        ? "deactivateView"
        : "normalView";
      if (this.ifSeemployeeDetails) {
        this.ifShowDetails = true;
      }
      this.clickRow = row;
    },
    select(selectedRows) {
      this.selectedRows = selectedRows;
    },
    deactivate(person) {
      this.$alert("确定对当前成员进行停用操作？", {
        confirmButtonText: "确定",
        type: "warning",
        showCancelButton: true,
        callback: async (action) => {
          if (action === "confirm") {
            let res = {};
            if (person) {
              res = await deactivateEmployee([person.employee_id]);
            } else {
              res = await deactivateEmployee(
                this.selectedRows.map((item) => {
                  return item.employee_id;
                })
              );
            }
            if (res.code === 20031) {
              this.$message({
                message: "停用成功",
                type: "success",
              });
              this.refrushPersons();
            }
          }
        },
      });
    },
    async restore(person) {
      this.$alert("确定对当前成员进行恢复操作？", {
        confirmButtonText: "确定",
        type: "warning",
        showCancelButton: true,
        callback: async (action) => {
          if (action === "confirm") {
            let res = {};
            if (person) {
              res = await restoreEmployee([person.employee_id]);
            } else {
              res = await restoreEmployee(
                this.selectedRows.map((item) => {
                  return item.employee_id;
                })
              );
            }
            if (res.code === 20031) {
              this.$message({
                message: "恢复成功",
                type: "success",
              });
              this.refrushPersons();
            }
          }
        },
      });
    },
    leftDialogSubmit() {
      this.$refs.leftDialogForm.validate(async (res) => {
        if (res) {
          let res = {};
          if (this.leftMode === "addSubDept") {
            // 添加子部门
            res = await addSubDept({
              dept_id: this.leftDialogCurrentDept.dept_id,
              add_dept: this.leftDialogForm.deptName,
            });
          } else if (
            this.leftDialogCurrentDept.dept_name !==
            this.leftDialogForm.deptName
          ) {
            // 修改名称
            res = await changeDeptName({
              dept_id: this.leftDialogCurrentDept.dept_id,
              new_name: this.leftDialogForm.deptName,
            });
          } else {
            this.leftDialogVisible = false;
          }
          if (res.code === 20011 || res.code === 20031) {
            this.$message.success(res.code === 20011 ? "添加成功" : "修改成功");
            this.leftDialogVisible = false;
            this.refrushPersons();
          } else if (res.code) {
            this.$message.error(res.msg);
          }
        }
      });
    },
    changeDialogVisible(visible) {
      this.dialogVisible = visible;
    },
    async dialogSubmit(selectedNodes) {
      let res = await setDeptHeader({
        persons: selectedNodes,
        dept_id: this.currentNode.dept_id,
      });
      if (res.code === 20011) {
        this.$message.success("设置成功");
        this.dialogVisible = false;
        window.location.reload();
      } else {
        this.$message.error(res.msg);
      }
    },
    changePassword(person) {
      this.changePasswordPerson = person;
      this.rightDialogVisible = true;
    },
    rightDialogSubmit() {
      this.$refs.rightForm.validate(async (res) => {
        if (res) {
          // 修改密码
          let res = await changePassword({
            employee_id: this.changePasswordPerson.employee_id,
            newPassword: this.rightDialogForm.newPassword,
          });
          if (res.code === 20031) {
            this.rightDialogVisible = false;
            this.$message({
              message: "保存成功",
              type: "success",
            });
            if (
              this.changePasswordPerson.employee_id ===
              JSON.parse(localStorage.getItem("userInfo")).employee_id
            ) {
              localStorage.removeItem("userInfo");
              localStorage.removeItem("cookie");
              this.$router.push("/login");
            }
          }
        }
      });
    },
    editPerson(row) {
      this.personDetailsType = "edit";
      this.ifShowDetails = true;
      this.clickRow = row;
      setTimeout(() => {
        this.$refs.personDetails.changeToEdit();
      });
    },
    handleSizeChange() {
      console.log("handleSizeChange");
    },
    handleCurrentChange() {
      console.log("handleCurrentChange");
    },
    refrushPersons() {
      this.nodeClick(this.currentNode);
    },
    async searchFn() {
      let res = await searchDept(this.searchContent);
      if (res.code === 20041) {
        this.searchDepts = res.data;
      }
    },
  },
};
</script>
<style lang="less" scoped>
.OrganizationalStructure .OrganizationalStructure-content {
  background-color: #fff;
  border-radius: 10px;
  .select-range-content {
    display: flex;
    height: calc(100vh - 160px);
    .left-content {
      padding: 20px 0;
      border-right: 1px solid #e9eaed;
      display: flex;
      flex-direction: column;
      .el-input {
        width: 240px;
        margin: 0 10px 10px 10px;
      }
      .el-tree {
        height: calc(100vh - 240px);
        :deep {
          .el-tree-node__content {
            padding-top: 10px !important;
            padding-bottom: 10px !important;
            box-sizing: content-box;
            font-size: 14px;
            .custom-tree-node {
              display: flex;
              flex: 1;
              justify-content: space-between;
              align-items: center;
            }
            i {
              display: none;
            }
          }
          &.el-tree--highlight-current
            .el-tree-node.is-current
            > .el-tree-node__content {
            background-color: #f0f7ff;
            position: relative;
            border-left: 2px solid #3c8cff;
            color: #3c8cff;
            i {
              display: block;
            }
          }
        }
      }
    }
    .right-content {
      width: 100%;
      padding: 20px 16px 10px;
      display: flex;
      flex-direction: column;
      .right-title {
        display: flex;
        justify-content: space-between;
        align-items: center;
        .title-left {
          display: flex;
          align-items: center;
          h1 {
            font-size: 16px;
            font-weight: normal;
            margin-right: 10px;
          }
          .el-icon-copy-document {
            cursor: pointer;
          }
        }
        & > a {
          font-size: 12px;
          color: #4c78fc;
        }
      }
      .buttons {
        display: flex;
        justify-content: flex-end;
        margin: 10px 0;
      }
      .el-table {
        width: 100%;
        min-height: calc(100vh - 308px);
        margin-bottom: 10px;
      }
      .el-pagination {
        display: flex;
        justify-content: end;
      }
    }
  }
}
</style>
<style lang="less">
.os-popper,
.os-operate-popper {
  .section-item {
    padding: 10px;
    cursor: pointer;
    &:hover {
      background-color: #f5f7fa;
    }
  }
  .section-id {
    border-top: 1px solid rgba(223, 220, 220, 0.9);
    color: #e9e9e9;
    padding: 8px;
  }
}
</style>
